package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.attendance.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentMapper;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysDepartment;
import com.nineclock.system.service.SysDepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class SysDepartmentServiceImpl implements SysDepartmentService {
    @Autowired
    SysDepartmentMapper departmentMapper;
    @Autowired
    SysCompanyUserMapper companyUserMapper;


    @Override
    public List<SysDepartmentDTO> queryDepartmentList() {
        List<SysDepartmentDTO> departmentDTOList = queryChildrenDepartmentList(0L);

        return departmentDTOList;
    }

    @Override
    public List<Long> queryDepartmentIds() {
        //   ------------->   顶级部门ids
        LambdaQueryWrapper<SysDepartment> departmentQW = new LambdaQueryWrapper<>();
        departmentQW.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        departmentQW.eq(SysDepartment::getParentId, 0);
        List<SysDepartment> departmentList = departmentMapper.selectList(departmentQW);
        List<Long> departmentIds = departmentList.stream().map(department -> {
            return department.getId();
        }).collect(Collectors.toList());
        return departmentIds;
    }

    @Override
    public List<DepartmentOrUserSimpleDTO> querySimpleDepartment(Long departmentId, Integer includeMember) {
        //健壮性判断
        if (departmentId == null || includeMember == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //创建返回值对象

        //查询部门
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysDepartment::getParentId, departmentId);
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(departmentList)) {
            List<DepartmentOrUserSimpleDTO> collect = departmentList.stream().map(departmentMapper -> {
                DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                departmentOrUserSimpleDTO.setId(departmentMapper.getId());
                departmentOrUserSimpleDTO.setName(departmentMapper.getName());
                departmentOrUserSimpleDTO.setType(1);
                return departmentOrUserSimpleDTO;
            }).collect(Collectors.toList());
            return collect;
        }

        //查询员工
        if (includeMember == 0){
            LambdaQueryWrapper<SysCompanyUser> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            wrapper1.eq(SysCompanyUser::getDepartmentId, departmentId);
            List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper1);
            if (CollectionUtil.isNotEmpty(companyUserList)) {
                List<DepartmentOrUserSimpleDTO> collect = companyUserList.stream().map(companyUser -> {
                    DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                    departmentOrUserSimpleDTO.setId(companyUser.getId());
                    departmentOrUserSimpleDTO.setType(2);
                    departmentOrUserSimpleDTO.setName(companyUser.getUserName());
                    return departmentOrUserSimpleDTO;
                }).collect(Collectors.toList());
                return collect;
            }
        }
        return new ArrayList<DepartmentOrUserSimpleDTO>();
    }

    @Override
    public List<Long> queryDepartmentsByUserId(Long companyUserId) {
        //健壮性判断
        List<Long> ids = new ArrayList<>();
        if (companyUserId != null){
            SysCompanyUser companyUser = companyUserMapper.selectById(companyUserId);   //员工id  ----查---->   最低层部门id (通过用户)
            Long departmentId = companyUser.getDepartmentId();
            ids.add(departmentId);

            SysDepartment department = departmentMapper.selectById(departmentId);  // 最低层部门id ------查----> 上级部门id
            Long parentId = department.getParentId();
            while (parentId != 0){
                ids.add(parentId);
                SysDepartment department1 = departmentMapper.selectById(parentId);
                parentId = department1.getParentId();
            }
        }
        return ids;
    }


    //获取子部门
    public List<SysDepartmentDTO> queryChildrenDepartmentList(Long parentId) {
        //先查顶级部门 (集合)
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getParentId, parentId);
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        List<SysDepartment> departments = departmentMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(departments)) {
            List<SysDepartmentDTO> departmentDTOList = BeanHelper.copyWithCollection(departments, SysDepartmentDTO.class);
            //遍历 查子级部门(聚合)
            for (SysDepartmentDTO departmentDTO : departmentDTOList) {
                List<SysDepartmentDTO> departmentDTOList1 = this.queryChildrenDepartmentList(departmentDTO.getId());
                departmentDTO.setChildren(departmentDTOList1);
            }
            return departmentDTOList;
        }
        //子级赋给父级
        return new ArrayList<>();
    }
}
